#include "Dict.h"

#include <fstream>
#include <iostream>

using namespace std;

Dict::Dict() 
	:mParent(NULL)
	,mLetter(' ')
{
	for (int i = 0; i < kNumLetters; i++)
	{
		mChildren[i] = NULL;
	}
	mIsWord = false;
}

Dict::~Dict()
{
	for (int i = 0; i < kNumLetters; i++)
	{
		if (mChildren[i])
		{
			delete mChildren[i];
		}
	}
}

void Dict::addWord(const char* wd)
{
	if (!wd) 
	{
		return;
	}
	if (!*wd)
	{
		mIsWord = true;
		return;
	}
	int c = idx(*wd);
	
	if (mChildren[c] == 0)
	{
		mChildren[c] = new Dict;
		mChildren[c]->mLetter = *wd;
		mChildren[c]->mParent = this;
	}

	mChildren[c]->addWord(wd+1);
}

bool Dict::isBoggleWord(const string& wd)
{
	if (wd.size()<2 || wd.size() > 25)
	{
		return false;
	}

	for (unsigned i = 0; i < wd.size(); ++i)
	{
		if (!isAlphabet(wd[i]))
		{
			return false;
		}
	}

	return true;
}

int Dict::loadFile(const char* filename)
{
	ifstream file(filename);
	if (!file)
	{
		return -1;
	}

	string line;
	int words = 0;
	while (file >> line)
	{
		if (!isBoggleWord(line))
		{
			continue;
		}

		addWord(line.c_str());
		words += 1;
	}

	return words;
}

bool Dict::isWord(const char* wd) const
{
	if (!wd)
	{
		return false;
	}

	if (!*wd)
	{
		return isWord();
	}
	
	if (!isAlphabet(*wd))
	{
		return false;
	}

	int c = idx(*wd);

	if (mChildren[c] != 0)
	{
		return mChildren[c]->isWord(wd+1);
	}

	return false;
}

unsigned int Dict::size() const 
{
	unsigned int size = 0;

	if (isWord()) 
	{
		size++;
	}

	for (int i = 0; i < kNumLetters; i++) 
	{
		if (mChildren[i] != 0) 
		{
			size += mChildren[i]->size();
		}
	}

	return size;
}

std::string Dict::getWord()
{
	std::string str;
	if(mIsWord)
	{
		std::string strTemp;
		strTemp += mLetter;

		Dict* pParent = mParent;
		while (pParent)
		{
			strTemp += pParent->mLetter;
			pParent = pParent->mParent;

			if(!pParent)
			{
				break;				
			}			
		};

		str.assign(strTemp.rbegin(), strTemp.rend());
	}

	return str;
}